package com.xygz.orm.internal;

import com.xygz.orm.SFunc;
import com.xygz.orm.ConditionWrapper;
import com.xygz.orm.exception.ORMCheckException;

import java.util.function.Predicate;

/**
 * 数据库修改器
 *
 * @param <Child> 子类型
 * @author xiyuan-lgz 2023-11-30 @version v1.0.0 新建与整理
 */
public interface Update<E, Child extends Update<E, Child>> {
    /**
     * 设置表别名
     *
     * @param alias                 表别名
     * @return                      当前查询器
     * @throws ORMCheckException   当 表名为空或者不规范时 抛出异常
     */
    public Child as(String alias) throws ORMCheckException;
    
    /**
     * 获取表别名
     * @return 表别名，
     */
    public String as();
    
    
    /**
     * 设置修改字段
     *
     * @param column 被修改的属性名 或者 数据库列名
     * @param value  字段值
     * @return 当前修改器;
     */
    public Child set(String column, Object value);
    
    /**
     * 设置修改字段
     *
     * @param column 被修改的属性名
     * @param value  字段值
     * @return 当前修改器;
     */
    public Child set(SFunc<E, ?> column, Object value);
    
    /**
     * 设置修改字段
     *
     * @param column    被修改的属性名 或者 数据库列名
     * @param value     字段值
     * @param predicate 设置条件， 如果返回 true 则修改，返回false 不进行修改
     * @return 当前修改器;
     */
    public Child set(boolean predicate, String column, Object value);
    
    /**
     * 设置修改字段
     *
     * @param column    被修改的属性名
     * @param value     字段值
     * @param predicate 设置条件， 如果返回 true 则修改，返回false 不进行修改
     * @return 当前修改器;
     */
    public Child set(boolean predicate, SFunc<E, ?> column, Object value);
    
    /**
     * 设置修改字段
     *
     * @param column    被修改的属性名 或者 数据库列名
     * @param value     字段值
     * @param predicate 设置条件， 如果返回 true 则修改，返回false 不进行修改
     * @return 当前修改器;
     */
    default Child set(Predicate<Object> predicate, String column, Object value) {
        return set(predicate.test(value), column, value);
    }
    
    /**
     * 设置修改字段
     *
     * @param column    被修改的属性
     * @param value     字段值
     * @param predicate 设置条件， 如果返回 true 则修改，返回false 不进行修改
     * @return 当前修改器;
     */
    default Child set(Predicate<Object> predicate, SFunc<E, ?> column, Object value) {
        return set(predicate.test(value), column, value);
    }
    
    /**
     * 设置修改字段
     * <p>
     * 需要注意的是 express sql 片段, 此种方式是不安全的，因为可能发生SQL 注入问题，请自行注意SQL 编码问题
     *
     * @param column     被修改的属性名 或者 数据库列名
     * @param expression sql 表达式：GREATEST(1, 5)
     * @return 当前修改器;
     */
    public Child setExpression(String column, String expression);
    
    
    /**
     * 设置修改字段
     * <p>
     * 需要注意的是 express sql 片段, 此种方式是不安全的，因为可能发生SQL 注入问题，请自行注意SQL 编码问题
     *
     * @param column     被修改的属性
     * @param expression sql 表达式：GREATEST(1, 5)
     * @return 当前修改器;
     */
    public Child setExpression(SFunc<E, ?> column, String expression);
    
    /**
     * 设置修改字段
     * <p>
     * 需要注意的是 express sql 片段, 此种方式是不安全的，因为可能发生SQL 注入问题，请自行注意SQL 编码问题
     *
     * @param column     被修改的属性名 或者 数据库列名
     * @param expression sql 表达式：GREATEST(1, 5)
     * @param predicate  设置条件， 如果返回 true 则修改，返回false 不进行修改
     * @return 当前修改器;
     */
    
    public Child setExpression(boolean predicate, String column, String expression);
    
    /**
     * 设置修改字段
     * <p>
     * 需要注意的是 express sql 片段, 此种方式是不安全的，因为可能发生SQL 注入问题，请自行注意SQL 编码问题
     *
     * @param column     被修改的属性名
     * @param expression sql 表达式，例如：GREATEST(1, 5)
     * @param predicate  设置条件， 如果返回 true 则修改，返回false 不进行修改
     * @return 当前修改器;
     */
    public Child setExpression(boolean predicate, SFunc<E, ?> column, String expression);
}
